#pragma once

#include <sys/epoll.h>
#include <unistd.h>
#include <iostream>
#include "Log.hpp"
#include "Common.hpp"

using namespace LogModule;

class Epoller{
public:

	Epoller(){
		_epfd = epoll_create(256);
		if(_epfd < 0){
			LOG(LogLevel::ERROR) << "epoll_create error";
		}
	}
	void ModEventHelper(int op, int sockfd, uint32_t events){
		struct epoll_event ev;
		ev.data.fd = sockfd;
		ev.events = events;
		int ctl_ret = epoll_ctl(_epfd, op, sockfd, &ev);
		if(ctl_ret < 0){
			LOG(LogLevel::ERROR) << "epoll_ctl error";
		}
	}

	void AddEvent(int sockfd, uint32_t events){
		ModEventHelper(EPOLL_CTL_ADD, sockfd, events);
	}

	void DelEvent(int sockfd, uint32_t events){
		ModEventHelper(EPOLL_CTL_DEL, sockfd, events);
	}

	void ModEvent(int sockfd, uint32_t events){
		ModEventHelper(EPOLL_CTL_MOD, sockfd, events);
	}

	int WaitEvent(struct epoll_event *recv, int maxnum, int timeout = -1){
		int wait_ret = epoll_wait(_epfd, recv, maxnum, timeout);
		if(wait_ret < 0){
			LOG(LogLevel::WARNING) << "epoll_wait error";
		}
		else if(wait_ret == 0){
			LOG(LogLevel::WARNING) << "epoll_wait timeout";
		}

		return wait_ret;
	}

private:
	int _epfd;

};